/** {{ struct.name }} **/
function {{ struct.name }}(opts, byteOffset) {
  if (new.target !== {{ struct.name }}) {
    if (typeof opts === "string") {
      // opts contains our stack byteOffset
      // byteOffset is unused
      let out = getStructFromStack(opts, {{ struct.name }}, STRUCT_CACHE_{{ struct.name }});
      out.reset();
      return out;
    } else if (typeof opts === "object" && byteOffset !== void 0) {
      // opts contains our initialization data
      // byteOffset contains the stack byteOffset
      let out = getStructFromStack(byteOffset, {{ struct.name }}, STRUCT_CACHE_{{ struct.name }});
      out.reset(opts);
      return out;
    } else {
      throw new Error(`Invalid Signature for '{{ struct.name }}'`);
    }
  }
  this.memoryBuffer = null;
  this.memoryAddress = BI0;
  this.$memoryOffset = 0x0;
  this.resetMemoryView = null;
  if (typeof opts === "object" && opts.$memoryOffset !== void 0) {
    this.memoryBuffer = opts.$memoryBuffer;
    this.memoryAddress = getAddressFromArrayBuffer(this.memoryBuffer) + BigInt(opts.$memoryOffset);
    this.$memoryOffset = opts.$memoryOffset | 0;
{{ getStructureMemoryViews(false) | safe }}
  } else {
    this.memoryBuffer = new ArrayBuffer({{ getStructureByteLength() | safe }});
    this.memoryAddress = getAddressFromArrayBuffer(this.memoryBuffer);
{{ getStructureMemoryViews(true) | safe }}
  }
  {% for member in struct.children %}
  {%- if isIgnoreableType(member) != true -%}
  {{ getConstructorInitializer(member) | safe }}
  {% endif -%}
  {%- endfor -%}
  {{ getStructureAutoSType() | safe }}
  if (typeof opts === "object") {
    {% for member in struct.children %}
    {%- if isIgnoreableType(member) != true -%}
    {%- if isFillableMember(struct, member) == true -%}
    if (opts.{{ member.name }} !== void 0) this.{{ member.name }} = opts.{{ member.name }};
    {% endif -%}
    {% endif -%}
    {%- endfor %}
  }
};

Object.defineProperties({{ struct.name }}.prototype, {
  {% for member in struct.children %}
  {%- if isIgnoreableType(member) != true -%}
  "{{ member.name }}": {
    get() {
      {{- getGetterProcessor(member) | safe }}
    },
    {% if isFillableMember(struct, member) == true -%}
    set(value) {
      {{- getSetterProcessor(member) | safe }}
    }
    {% endif -%}
  },
  {% endif -%}
  {% endfor %}
});

{{ struct.name }}.prototype.reset = function reset(opts) {
  if (this.resetMemoryView === null) {
    this.resetMemoryView = new Uint8Array(this.memoryBuffer, this.$memoryOffset, {{ getStructureByteLength() | safe }});
  }
  this.resetMemoryView.set(STRUCT_RESET_CACHE["{{ getStructureByteLength() | safe }}"], 0x0);
  {% for member in struct.children %}
  {%- if isIgnoreableType(member) != true -%}
  {{ getConstructorResetter(member) | safe }}
  {% endif -%}
  {%- endfor -%}
  {{ getStructureAutoSType() | safe }}
  if (typeof opts === "object") {
    {% for member in struct.children %}
    {%- if isIgnoreableType(member) != true -%}
    {%- if isFillableMember(struct, member) == true -%}
    if (opts.{{ member.name }} !== void 0) this.{{ member.name }} = opts.{{ member.name }};
    {% endif -%}
    {% endif -%}
    {%- endfor %}
  }
};

{{ struct.name }}.prototype.flush = function flush() {
  {% for member in struct.children -%}
  {%- if isIgnoreableType(member) != true -%}
  {%- if isFlushableMember(member) == true %}
  {%- if isFillableMember(struct, member) == true %}
  {{ getFlusherProcessor(member) | safe }}
  {% endif -%}
  {%- endif -%}
  {%- endif -%}
  {%- endfor %}
  return true;
};

{{ struct.name }}.prototype.reflect = function reflect(memoryAddress) {
  {% if struct.returnedonly == true -%}
  let srcBuffer = getArrayBufferFromAddress(memoryAddress, BigInt({{ getStructureByteLength() | safe }}));
  let dstBuffer = this.memoryBuffer;
  let srcView = new Uint8Array(srcBuffer);
  let dstView = new Uint8Array(dstBuffer);
  dstView.set(srcView.subarray(0x0, {{ getStructureByteLength() | safe }}), 0x0);
  {%- endif -%}
};

{{ struct.name }}.createCopyFrom = function createCopyFrom(original) {
  let copy = new {{ struct.name }}();
  {% for member in struct.children -%}
  {%- if isIgnoreableType(member) != true -%}
  {{ getCopyOperation(member) | safe }}
  {% endif -%}
  {%- endfor %}
  return copy;
};

{{ struct.name }}.byteLength = {{ getStructureByteLength() | safe }};

{{ struct.name }}.memoryLayout = {
  {%- for member in struct.children -%}
  {%- if isIgnoreableType(member) != true %}
  {{ member.name }}: {
    byteOffset: {{ getStructureMemberByteOffset(member) | safe }},
    byteLength: {{ getStructureMemberByteLength(member) | safe }}
  },
  {%- endif -%}
  {%- endfor %}
};
